
#include "cgzAFun.h"
#include "cgzCThreadPool.h"

void safeQuiteExec(int signum)
{
    auto pool = cgzCThreadPool::Instance();
    pool->shutdown();
    std::cerr << "wait All threads quit." << std::endl;
}

void safeGCoreDump(int signum)
{
    const char *msg = "Generating core dump...\n";
    write(STDERR_FILENO, msg, strlen(msg));

    // 直接在当前进程中执行gcore
    std::string cmd = fmt::format("gcore {}", getpid());
    system(cmd.c_str());
}

// 信号处理函数
void signalHandler(int signum)
{
    std::cerr << "Received signal: " << signum << std::endl;
    // 程序core dump
    safeGCoreDump(signum);
    // 设置安全退出线程
    safeQuiteExec(signum);
}

void intiCore()
{
    // 设置 core dump 限制
    struct rlimit core_limit;
    // core_limit.rlim_cur = RLIM_INFINITY; // 软限制（当前进程）
    // core_limit.rlim_max = RLIM_INFINITY; // 硬限制（系统允许的最大值）
    core_limit.rlim_cur = 1 * 1024 * 1024 * 1024;
    core_limit.rlim_max = 1 * 1024 * 1024 * 1024;
    if (setrlimit(RLIMIT_CORE, &core_limit) == -1)
    {
        perror("setrlimit failed");
    }
    else
    {
        std::cout << "Core dump enabled (unlimited size)\n";
    }

    // 注册信号处理函数
    signal(SIGQUIT, signalHandler); // 处理 3退出信号 (Ctrl-\)
    signal(SIGILL, signalHandler);  // 处理 4非法指令信号
    signal(SIGABRT, signalHandler); // 处理 6中止信号
    signal(SIGFPE, signalHandler);  // 处理 8浮点异常信号
    signal(SIGKILL, signalHandler); // 处理 9强制终止信号 kill -9
    signal(SIGSEGV, signalHandler); // 处理 11段错误信号
    signal(SIGTERM, signalHandler); // 处理 15终止信号
}

void lookMems()
{
    // 获取已分配的内存
    size_t allocated;
    size_t sz = sizeof(allocated);
    mallctl("stats.allocated", &allocated, &sz, NULL, 0);

    // 获取活动内存
    size_t active;
    sz = sizeof(active);
    mallctl("stats.active", &active, &sz, NULL, 0);

    // 获取常驻内存
    size_t resident;
    sz = sizeof(resident);
    mallctl("stats.resident", &resident, &sz, NULL, 0);

    std::cout << "分配内存: " << allocated / 1024 / 1024 << " MB\n";
    std::cout << "活动内存: " << active / 1024 / 1024 << " MB\n";
    std::cout << "常驻内存: " << resident / 1024 / 1024 << " MB\n";
}

long diffsec = 0;
long diffmls = 0;
long diffmcs = 0;
template <typename DurationType>
auto autonow()
{
    using namespace std::chrono;
    auto now = system_clock::now();
    return duration_cast<DurationType>(now.time_since_epoch()).count();
}

long fnowsec()
{
    return autonow<std::chrono::seconds>() + diffsec;
}

long fnowmls()
{
    return autonow<std::chrono::milliseconds>() + diffmls;
}

long fnowmcs()
{
    return autonow<std::chrono::microseconds>() + diffmcs;
}

long fdifsec(long sec)
{
    diffsec += sec;
    diffmls = diffsec * 1000;
    diffmcs = diffmls * 1000;
    return fnowsec();
}

std::string get_current_date()
{
    auto now = std::chrono::system_clock::now();
    auto time_t_now = std::chrono::system_clock::to_time_t(now);
    std::tm local_tm = *std::localtime(&time_t_now);

    std::ostringstream oss;
    oss << std::put_time(&local_tm, "%Y-%m-%d");
    return oss.str();
}

std::string cxx_trace()
{
    std::ostringstream oss;
    oss << boost::stacktrace::stacktrace();
    return oss.str();
}

void reverseBytes(const char *src, char *tar, uint8_t size)
{
    for (uint8_t i = 0; i < size; i++)
    {
        tar[i] = src[size - i - 1];
    }
}

// 判断字符串是否包含中文字符
bool containsChinese(const std::string &str)
{
    for (const auto &c : str)
    {
        if ((unsigned char)c >= 0x80)
        { // 判断是否为非 ASCII 字符
            return true;
        }
    }
    return false;
}

// 将 UTF-8 编码的字符串转换为宽字符串
std::wstring utf8ToWstring(const std::string &str)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(str);
}

// 将宽字符串转换为 UTF-8 编码的字符串
std::string wstringToUtf8(const std::wstring &wstr)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.to_bytes(wstr);
}

std::string base64_encode(const unsigned char *buffer, size_t length)
{
    // 计算编码后的长度
    int encoded_length = 4 * ((length + 2) / 3);
    auto encoded_buffer = (unsigned char *)malloc(encoded_length + 1); // +1 为 null 终止符

    // 使用 EVP_EncodeBlock 进行 Base64 编码
    EVP_EncodeBlock(encoded_buffer, buffer, length);

    // 将编码结果转换为 std::string
    std::string encoded(reinterpret_cast<char *>(encoded_buffer), encoded_length);

    // 释放临时缓冲区
    free(encoded_buffer);

    return encoded;
}

const std::string wsGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // WebSocket GUID
std::string websocket_generate_acceptkey(const std::string &key)
{
    // 拼接 Sec-WebSocket-Key 和 GUID
    std::string concatenated = key + wsGUID;

    // 计算 SHA-1 哈希
    unsigned char hash[SHA_DIGEST_LENGTH];
    SHA1(reinterpret_cast<const unsigned char *>(concatenated.c_str()), concatenated.size(), hash);

    // Base64 编码 SHA-1 哈希
    return base64_encode(hash, SHA_DIGEST_LENGTH);
}

// 处理客户端的握手请求
std::string websocket_check_handshake(std::string &request)
{
    // 解析 Sec-WebSocket-Key
    std::string key;
    std::istringstream request_stream(request);
    std::string line;
    while (std::getline(request_stream, line))
    {
        if (line.find("Sec-WebSocket-Key:") != std::string::npos)
        {
            key = line.substr(line.find(":") + 2);          // 获取键值
            key.erase(key.find_last_not_of(" \n\r\t") + 1); // 去除前后空格
            break;
        }
        if (line.empty())
        {
            break; // 请求头结束
        }
    }

    // 计算 Sec-WebSocket-Accept
    std::string accept_key = websocket_generate_acceptkey(key);

    // 构建握手响应
    std::string response = "HTTP/1.1 101 Switching Protocols\r\n"
                           "Upgrade: websocket\r\n"
                           "Connection: Upgrade\r\n"
                           "Sec-WebSocket-Accept: " +
                           accept_key + "\r\n\r\n";

    // 发送握手响应
    return response;
}

std::string websocket_generate_handkey()
{
    return base64_encode(reinterpret_cast<const unsigned char *>(std::to_string(fnowmls()).c_str()), 8);
}
// 处理客户端的握手请求
std::string websocket_generate_handshake(std::string &key, std::string &ip, int port)
{
    // 构建握手请求
    std::string request = "GET / HTTP/1.1\r\n"
                          "Host:" +
                          ip + ":" + std::to_string(port) + "\r\n" +
                          "Upgrade: websocket\r\n"
                          "Connection: Upgrade\r\n"
                          "Sec-WebSocket-Key: " +
                          key + "\r\n" +
                          "Sec-WebSocket-Version:13\r\n\r\n";

    // 发送握手请求
    return request;
}

// 验证握手响应
bool websocket_validate_handshake(const std::string &response, const std::string &key)
{
    std::istringstream response_stream(response);
    std::string line;

    // 检查状态行
    std::getline(response_stream, line);
    if (line.find("101 Switching Protocols") == std::string::npos)
    {
        std::cerr << "Invalid response status." << std::endl;
        return false;
    }

    // 检查 Upgrade 和 Connection 头
    bool upgrade_found = false;
    bool connection_found = false;

    while (std::getline(response_stream, line) && !line.empty())
    {
        if (line.find("Upgrade: websocket") != std::string::npos)
        {
            upgrade_found = true;
        }
        if (line.find("Connection: Upgrade") != std::string::npos)
        {
            connection_found = true;
        }
        if (upgrade_found && connection_found)
        {
            break;
        }
    }

    if (!upgrade_found || !connection_found)
    {
        std::cerr << "Missing Upgrade or Connection header." << std::endl;
        return false;
    }

    // 检查 Sec-WebSocket-Accept 头
    std::string accept_key;
    while (std::getline(response_stream, line) && !line.empty())
    {
        if (line.find("Sec-WebSocket-Accept:") != std::string::npos)
        {
            accept_key = line.substr(line.find(":") + 2);                 // 获取值
            accept_key.erase(accept_key.find_last_not_of(" \n\r\t") + 1); // 去除前后空格
            break;
        }
    }

    std::string expected_accept_key = websocket_generate_acceptkey(key);
    if (accept_key != expected_accept_key)
    {
        std::cerr << "Invalid Sec-WebSocket-Accept key." << std::endl;
        return false;
    }

    return true;
}

cgzCWDecode::cgzCWDecode()
    : fs(WEBSOCKET_D_NONE),
      fin(0),
      rsv1(0),
      rsv2(0),
      rsv3(0),
      opcode(0),
      mask(0),
      payload_length(0),
      masking_key{0, 0, 0, 0},
      decode_len(0),
      rt(WEBSOCKET_SEND_NONE)
{
    memset(decode_data, 0, READLEN);
}

cgzCWDecode::~cgzCWDecode()
{
}

bool webscoket_encode_message(const char *data, int len, int t, bool use_mask, char **output, int &outlen, const char *reason)
{
    outlen = 0;
    uint16_t tlen = 0;
    char tc[READLEN];
    char mask[MASK_LENGTH] = {0};

    // 生成随机掩码
    if (use_mask)
    {
        srand(static_cast<unsigned int>(time(nullptr))); // 初始化随机数种子
        for (int i = 0; i < MASK_LENGTH; ++i)
        {
            mask[i] = static_cast<char>(rand() % 256); // 生成0-255之间的随机字节
        }
    }

    switch (t)
    {
    case WEBSOCKET_SEND_HAND:
    {
        *output = (char *)malloc(len);
        memcpy(*output, data, len);
        outlen = len;
        return true;
    }
    case WEBSOCKET_SEND_TEXT:
    {
        tc[tlen++] = (0x80 | 0x01);
        break;
    }
    case WEBSOCKET_SEND_BINARY:
    {
        tc[tlen++] = (0x80 | 0x02);
        break;
    }
    case WEBSOCKET_SEND_DISC:
    {
        tc[tlen++] = (0x80 | 0x08);
        tc[tlen++] = data[0];
        tc[tlen++] = data[1];
        if (reason == nullptr)
        {
            *output = (char *)malloc(tlen);
            memcpy(*output, tc, tlen);
            outlen = tlen;
            return true;
        }
        else
        {
            int reasonlen = strlen(reason);
            *output = (char *)malloc(tlen + reasonlen);
            memcpy(*output, tc, tlen);
            memcpy(*output + tlen, reason, reasonlen);
            tlen += reasonlen;
            outlen = tlen;
            return true;
        }
    }
    case WEBSOCKET_SEND_PING:
    {
        tc[tlen++] = (0x80 | 0x09);
        break;
    }
    case WEBSOCKET_SEND_PONG:
    {
        tc[tlen++] = (0x80 | 0x0a);
        break;
    }
    }

    if (len < 126)
    {
        tc[tlen++] = len;
    }
    else if (len < 65536)
    {
        tc[tlen++] = 126 | (use_mask ? 0x80 : 0);
        uint16_t len16 = len;
        reverseBytes((char *)&len16, tc + tlen, 2);
        tlen += 2;
    }
    else
    {
        tc[tlen++] = 127 | (use_mask ? 0x80 : 0);
        uint64_t len64 = len;
        reverseBytes((char *)&len64, tc + tlen, 8);
        tlen += 8;
    }

    // 分配输出缓冲区
    *output = (char *)malloc(tlen + (use_mask ? MASK_LENGTH : 0) + len);
    memcpy(*output, tc, tlen);
    if (use_mask)
    {
        memcpy(*output + tlen, mask, MASK_LENGTH); // 添加掩码
        tlen += MASK_LENGTH;
        // 应用掩码到数据
        for (int i = 0; i < len; ++i)
        {
            (*output)[tlen + i] = data[i] ^ mask[i % MASK_LENGTH]; // 使用掩码进行异或
        }
    }
    else
    {
        memcpy(*output + tlen, data, len); // 不使用掩码，直接复制数据
    }

    outlen = tlen + len;
    return true;
}

/// @brief 解码消息
/// @param cire
/// @param de
/// @return
bool webscoket_decode_message(cgzCireBuffer &cire, cgzCWDecode &de)
{
    while (cire.used() > 0 || de.fs != WEBSOCKET_D_END)
    {
        switch (de.fs)
        {
        case WEBSOCKET_D_NONE: // 开始读取消息头
        {
            if (cire.used() < 2)
            {
                return false;
            }

            // 读取数据
            char data[2] = {0, 0};
            cire.read(data, sizeof(data));
            cire.pop(sizeof(data));

            de.fin = (data[0] & 0x80) >> 7;
            de.rsv1 = (data[0] & 0x40) >> 6;
            de.rsv2 = (data[0] & 0x20) >> 5;
            de.rsv3 = (data[0] & 0x10) >> 4;
            de.opcode = data[0] & 0x0f;
            de.mask = (data[1] & 0x80) >> 7;
            de.payload_length = data[1] & 0x7f;
            de.fs = WEBSOCKET_D_PAYLOAD_LEN;
        }
        break;
        case WEBSOCKET_D_PAYLOAD_LEN: // 读取消息体长度
        {
            switch (de.payload_length)
            {
            case 126:
            {
                if (cire.used() < 2)
                {
                    return true;
                }

                char data[2] = {0, 0};
                cire.read(data, sizeof(data));
                cire.pop(sizeof(data));

                char d[2] = {0, 0};
                reverseBytes(data, d, sizeof(d));
                de.payload_length = *((uint16_t *)d);
            }
            break;
            case 127:
            {
                if (cire.used() < 8)
                {
                    return false;
                }

                char data[8] = {0};
                cire.read(data, sizeof(data));
                cire.pop(sizeof(data));

                char d[8] = {0, 0, 0, 0, 0, 0, 0, 0};
                reverseBytes(data, d, sizeof(d));
                de.payload_length = *((uint64_t *)d);
            }
            break;
            }
            de.fs = de.mask ? WEBSOCKET_D_MASKING_KEY : WEBSOCKET_D_PAYLOAD;
        }
        break;
        case WEBSOCKET_D_MASKING_KEY: // 读取掩码密钥
        {
            if (cire.used() < sizeof(de.masking_key))
            {
                return false;
            }

            cire.read(de.masking_key, sizeof(de.masking_key));
            cire.pop(sizeof(de.masking_key));
            de.fs = WEBSOCKET_D_PAYLOAD;
        }
        break;
        case WEBSOCKET_D_PAYLOAD: // 读取消息体
        {
            if (cire.used() < de.payload_length)
            {
                return false;
            }

            if (de.mask)
            {
                cire.read(de.decode_data, de.payload_length, de.masking_key);
                de.decode_len += de.payload_length;
            }
            else
            {
                cire.read(de.decode_data, de.payload_length);
                de.decode_len += de.payload_length;
            }
            switch (de.opcode)
            {
            case 0x01:
                // 文本消息
                de.decode_data[de.decode_len++] = 0;
                de.rt = WEBSOCKET_SEND_TEXT;
                break;
            case 0x02:
                // 二进制消息
                de.rt = WEBSOCKET_SEND_BINARY;
                break;
            case 0x08:
                // 关闭连接
                de.rt = WEBSOCKET_SEND_DISC;
                break;
            case 0x09:
                // ping消息
                de.rt = WEBSOCKET_SEND_PING;
                break;
            case 0x0a:
                // pong消息
                de.rt = WEBSOCKET_SEND_PONG;
                break;
            default:
                assert(false);
                break;
            }

            de.fs = WEBSOCKET_D_END;
            cire.pop(de.payload_length);
            break;
        default:
            assert(false);
            break;
        }
        }
    }
    return de.fs == WEBSOCKET_D_END;
}